package com.juyu.miliao.api.config;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zc
 * @date 18-11-20下午7:03
 */
public class SegmentedLockManager {

    private static final int DEFAULTS_LOCK_SIZE = 17;
    private final Lock[] locks;
    private final int lockSize;

    public SegmentedLockManager(int lockSize) {
        if (lockSize <= 0)
            throw new IllegalArgumentException();
        this.lockSize = lockSize;
        locks = new Lock[lockSize];
        for (int i = 0; i < lockSize; i++) {
            final Lock lock = new ReentrantLock();
            locks[i] = lock;
        }
    }

    public SegmentedLockManager() {
        this(DEFAULTS_LOCK_SIZE);
    }

    private int computeSlot(String key) {
        return Math.abs(key.hashCode()) % lockSize;
    }

    public Lock getLock(String key) {
        return locks[computeSlot(key)];
    }

    public void sync(String key, Runnable operate) {
        Lock lock = getLock(key);
        lock.lock();
        try {
            operate.run();
        } finally {
            lock.unlock();
        }
    }

}